package scenebuilders;

import java.util.LinkedList;
import java.util.List;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Group;
import javax.media.j3d.SpotLight;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

public class LightsBuilder {		
	public class LightsProperties {
		public Group sceneRoot = null;
		public Point3f position = new Point3f(0, 2, 0);
		public Vector3f direction = new Vector3f(0.0f, -0.5f, -1.0f);
		public Color3f ambient = new Color3f(.2f, .2f, .2f);
		public Color3f color = new Color3f(1, 1, 1);
		public float concentration = 20f;
		public float spreadAngle = 80f;
	}
					
	Group sceneRoot;
	public LightsProperties lpGlobal = new LightsProperties();
	List<LightsProperties> spotLights = new LinkedList<LightsProperties>();
	
	public LightsBuilder(Group sceneRoot) {
		super();
		this.sceneRoot = sceneRoot;
	}		

	public void CreateLights() {
		CreateGlobalLight();
		for (LightsProperties spotLight : spotLights) {
			CreateSpotLight(spotLight);
		}			
	}

	public void RegisterSpotLights(int count, float concentration, float spreadAngle) {
		for (int i = 0; i < count; i++) {
			LightsProperties lp = new LightsProperties();
			lp.concentration = concentration;
			lp.spreadAngle = spreadAngle;
			spotLights.add(lp);
		}
	}

	public void SetSpotLight(int index, Vector3f direction, Point3f position) {
		LightsProperties lp = spotLights.get(index);
		lp.direction = direction;
		lp.position = position;
	}

	private void CreateGlobalLight() {
		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
				0.0), 30.0);

		// Set up the directed light
		Color3f light1Color = lpGlobal.color;
		Vector3f light1Direction = lpGlobal.direction;
		DirectionalLight light1 = new DirectionalLight(light1Color,
				light1Direction);
		light1.setInfluencingBounds(bounds);
		sceneRoot.addChild(light1);

		// Set up the ambient light
		Color3f ambientColor = lpGlobal.ambient;
		AmbientLight ambientLightNode = new AmbientLight(ambientColor);
		ambientLightNode.setInfluencingBounds(bounds);
		sceneRoot.addChild(ambientLightNode);
	}

	private void CreateSpotLight(LightsProperties lp) {
		// Creates a SpotLight, and places it inside the LightShade - acts
		// as a
		// light bulb
		SpotLight sl = new SpotLight();
		sl.setInfluencingBounds(new BoundingSphere(new Point3d(0.0, 0.0,
				0.0), 30.0));
		sl.setPosition(lp.position);
		sl.setSpreadAngle((float) Math.toRadians(lp.spreadAngle));
		sl.setConcentration(lp.concentration);
		sl.setDirection(lp.direction);
		sl.setEnable(true);
		sl.setColor(lp.color);
		
		if (lp.sceneRoot == null)
			sceneRoot.addChild(sl);
		else
			lp.sceneRoot.addChild(sl);
	}
}